package net.sh.dpinfrastructure.support.spring.configuration;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.FutureTask;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;

import com.google.common.collect.Lists;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;

import net.sh.dpinfrastructure.config.DPConfig;
import net.sh.dpinfrastructure.mongo.DPMongoSource;

/**
 * 
 * mongodb配置类
 * 
 * @version 1.0
 * @since JDK1.7
 * @author shaohui
 * @company 上海朝阳永续信息技术有限公司
 * @copyright (c) 2016 SunTime Co'Ltd Inc. All rights reserved.
 * @date 2016年8月8日 下午2:44:04
 */
@Configuration
@Import(DPConfigConfiguration.class)
public class DPMongodbConfiguration {
    
    /**
     * 默认的连接超时时间（ms）
     */
    private static final int CONNECT_TIMEOUT = 2000;
    
    /**
     * 默认的最大连接数（单个节点）
     */
    private static final int MAX_CONNECT_PER_HOST = 10;
    
    /**
     * 默认的最小连接数（单个节点）
     */
    private static final int MIN_CONNECT_PER_HOST = 5;
    
    /**
     * 空闲链接最长存活时间
     */
    private static final int MAX_CONNECTION_IDLE_TIME = 2 * 60 * 1000;
    
    /**
     * 连接池连接耗尽时线程请求连接的最大等待时间
     */
    private static final int MAX_WAIT_TIME = 10 * 1000;
    
    /**
     * 最大socket超时时间
     */
    private static final int MAX_SOCKET_TIMEOUT = 20 * 1000;
    
    @Bean
    @Primary
    public DPMongoSource getDPMongodb(DPConfig configer) {
        String address = configer.get("module.mongo.address");
        String database = configer.get("module.mongo.db");
        String username = configer.get("module.mongo.user");
        String password = configer.get("module.mongo.password");
        MongoCredential credential = MongoCredential.createScramSha1Credential(username, database, password.toCharArray());
        List<ServerAddress> seeds = new ArrayList<>();
        String[] hostAndPortArray = address.split(";");
        for (String hostAndPortStr : hostAndPortArray) {
            String[] hostAndPort = hostAndPortStr.split(":");
            ServerAddress serverAddress = new ServerAddress(hostAndPort[0], Integer.parseInt(hostAndPort[1]));
            seeds.add(serverAddress);
        }
        
        MongoClientOptions options = new MongoClientOptions
                .Builder()
                .connectionsPerHost(configer.getIntValue("module.mongo.max_connect_perhost", MAX_CONNECT_PER_HOST))
                .connectTimeout(configer.getIntValue("module.mongo.connect_timeout", CONNECT_TIMEOUT))
                .cursorFinalizerEnabled(true)
                .maxConnectionIdleTime(configer.getIntValue("module.mongo.max_connection_idle_time", MAX_CONNECTION_IDLE_TIME))
                .maxWaitTime(configer.getIntValue("module.mongo.max_wait_time", MAX_WAIT_TIME))
                .minConnectionsPerHost(configer.getIntValue("module.mongo.min_connect_perhost", MIN_CONNECT_PER_HOST))
                .socketTimeout(configer.getIntValue("module.mongo.max_socket_timeout", MAX_SOCKET_TIMEOUT))
                .applicationName(configer.get("module.application.name", "dataplatform")) // 设置应用名，方便定位异常操作
                .build();
        MongoClient mongoClient = new MongoClient(seeds, Lists.newArrayList(credential), options);
        return new DPMongoSource(mongoClient, database);
    }
}
